package xjggb.algorithm.排序.sort;

import java.text.DecimalFormat;

public abstract class Sort<T extends Comparable<T>> implements Comparable<Sort<T>>  {
    protected T[] array;  // 数组
    private Long time;   // 执行时间
    protected int cmpCount; //比较次数
    protected int  swapCount; //位置交换次数
    private DecimalFormat fmt = new DecimalFormat("#.00");

    public void sort(T[] array){
        if (array == null || array.length < 2) return;
        this.array=array;

        long l = System.currentTimeMillis();
        sort();//执行排序
        time=System.currentTimeMillis()-l;
    }

    protected abstract void sort();
    /*
     * 返回值等于0，代表 array[i1] == array[i2]
     * 返回值小于0，代表 array[i1] < array[i2]
     * 返回值大于0，代表 array[i1] > array[i2]
     */
    protected int cmp(int v1,int v2){
        cmpCount++;
        return array[v1].compareTo(array[v2]);
    }

    protected int cmp(T v1, T v2) {
        cmpCount++;
        return v1.compareTo(v2);
    }


    /*
    * 位置交换
    * */
    protected void swap(int v1,int v2){
        swapCount++;
        T tmp= array[v1];
        array[v1]=array[v2];
        array[v2]=tmp;
    }

    private String numberString(int number) {
        if (number < 10000) return "" + number;

        if (number < 100000000) return fmt.format(number / 10000.0) + "万";
        return fmt.format(number / 100000000.0) + "亿";
    }


    @Override
    public String toString() {
        String timeStr = "耗时：" + (time / 1000.0) + "s(" + time + "ms)";
        String compareCountStr = "比较：" + numberString(cmpCount);
        String swapCountStr = "交换：" + numberString(swapCount);

        StringBuilder stringBuilder = new StringBuilder();
        for (T t : array) {
            stringBuilder.append(t+">");
        }

//        String stableStr = "稳定性：" + isStable();
        return "【" + getClass().getSimpleName() + "】\n"
//                + stableStr + " \t"
                + timeStr + " \t"
                + compareCountStr + "\t "
                + swapCountStr + "\n"
                + stringBuilder.toString() + "\n"
                + "------------------------------------------------------------------";

    }

    public int compareTo(Sort<T> o) {
        int result = (int)(time - o.time);
        if (result != 0) return result;

        result = cmpCount - o.cmpCount;
        if (result != 0) return result;

        return swapCount - o.swapCount;
    }


//    private boolean isStable() {
//        if (this instanceof RadixSort) return true;
//        if (this instanceof CountingSort) return true;
//        if (this instanceof ShellSort) return false;
//        if (this instanceof SelectionSort) return false;
//        Student[] students = new Student[20];
//        for (int i = 0; i < students.length; i++) {
//            students[i] = new Student(i * 10, 10);
//        }
//        sort((T[]) students);
//        for (int i = 1; i < students.length; i++) {
//            int score = students[i].score;
//            int prevScore = students[i - 1].score;
//            if (score != prevScore + 10) return false;
//        }
//        return true;
//    }
}
